package com.kaguya.composite;

import java.util.ArrayList;
import java.util.List;

/**
 * 结构性 组合模式：适用于整体与局部差异不大的部分，更好地展示树形结构
 * 粗浅认为是A类中有属性是一个List<A>，其孩子部分仍然是一个自己,套娃
 *
 * 透明模式：抽象类规定了所有孩子的方法，使用者不关心是哪种类型的孩子节点：有的孩子用不到的节点也要继承
 * 安全组合模式：抽象类只规定基础的方法，剩下的扩展实现由子类自己去实现，下面的例子就是安全组合模式
 */
public class Composite {
    public static void main(String[] args) {
        Folder root = new Folder("root",1);
        File file1 = new File("file1.txt");
        Folder hello = new Folder("hello",2);

        root.add(file1);
        root.add(hello);

        File file2 = new File("file2.cfg");
        hello.add(file2);

        root.print();
    }
}

/**
 * 目录抽象类
 */
abstract class Directory {
    protected String name;

    public Directory(String name) {
        this.name = name;
    }

    public abstract void print();
}

/**
 * 文件夹类
 */
class Folder extends Directory{

    private List<Directory> folders;

    private Integer level;

    public Folder(String name,Integer level) {
        super(name);
        this.level = level;
        this.folders = new ArrayList<>();
    }


    @Override
    public void print() {
        System.out.println(super.name);
        for (Directory folder : this.folders) {
            //控制显示格式
            if(this.level != null){
                for(int  i = 0; i < this.level; i ++){
                    //打印空格控制格式
                    System.out.print("  ");
                }
                for(int  i = 0; i < this.level; i ++){
                    //每一行开始打印一个+号
                    if(i == 0){ System.out.print("+"); }
                    System.out.print("-");
                }
            }
            //打印名称
            folder.print();
        }
    }
    public boolean add(Directory dir) {
        return this.folders.add(dir);
    }

    public boolean remove(Directory dir) {
        return this.folders.remove(dir);
    }

    public Directory get(int index) {
        return this.folders.get(index);
    }

    public void list(){
        for (Directory dir : this.folders) {
            System.out.println(dir.name);
        }
    }
}

/**
 * 文件
 */
class File extends Directory{

    public File(String name) {
        super(name);
    }

    @Override
    public void print() {
        System.out.println(super.name);
    }
}